home *** CD-ROM | disk | FTP | other *** search
/ Gekkan Dennou Club 147 / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z / Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin / fdimg / —‹Œêsrc.lzh / buff.c < prev    next >
C/C++ Source or Header  |  1993-01-04  |  12KB  |  498 lines

  1. #include    "3DDEF.H"
  2. #include    "GLOBAL.H"
  3. #include    "FORWARD.H"
  4. #include    "XCODE.H"
  5.  
  6. static UBYTE l[VERY_LONG_LINE], s[VERY_LONG_LINE], w[VERY_LONG_LINE];    /* 十分なエリア */
  7.  
  8. /* フラグ=1で、最初に情報を付けてセーブする */
  9. /* h から last の前の行までをセーブする */
  10. /* fn が NULL ならば、カレントの名前で、さもなくば fn の名前でセーブする */
  11. int
  12. buff_save_file(int flag,UNIT *h,UNIT *last,STR fn)
  13. {
  14.     register UNIT *wp;
  15.     register UBYTE *p,*q;
  16.     register UBYTE c;
  17.     register FILE *fp;
  18.     int writeline = 0;
  19.     UBYTE s[VERY_LONG_LINE * 4];
  20.     UBYTE d[VERY_LONG_LINE * 4];
  21.     UBYTE fname[MAXLINE];
  22.     UBYTE tname[MAXLINE];
  23.     FILE *fpb;
  24.  
  25.     if (fn) {            /* 指定があるなら */
  26.         strcpy(fname,fn);    /* それ */
  27.     } else {            /* さもなくば */
  28.         strcpy(fname,FILE_NAMES[WDATA[CWN].WTEXTS].CONTENT);    /* カレントの名前を得る */
  29.     }
  30.     etc_get_tname(tname,fname);
  31.     if (!*tname) {
  32.         return(0);
  33.     }
  34.  
  35.     under_print((STR)"[書き出し中...]");
  36.     if (!(fp = fopen((char *)tname,"wb"))) {
  37.         error("ファイルの書き込みオープンが出来ません");
  38.         return(0);
  39.     }
  40.  
  41.     if (flag) {
  42.         fprintf(fp,"[This is a ThunderWord Text]\x0d\x0a");
  43.         fprintf(fp,"[WIDTH=%d]\x0d\x0a",CURRENT_JIZUME);
  44.         fprintf(fp,"[LWIDTH=%d]\x0d\x0a",(!!LYW_UPPER)+(!!LYW_UNDER)*2);
  45.         fprintf(fp,"[PAGE=%d]\x0d\x0a",PAGE);
  46.         fprintf(fp,"[CR=%d]\x0d\x0a",CR_VIEW);        /* 改行を表示するか */
  47.         fprintf(fp,"[TAB=%d,%d]\x0d\x0a",TAB_LENGTH,TAB_VIEW);    /* タブの長さと、表示 */
  48.         if (sysflag & 0b1) {
  49.             fprintf(fp,"[HGAP=%d]\x0d\x0a",PRN_H_PITCH);    /* 横ギャップ */
  50.             fprintf(fp,"[VGAP=%d]\x0d\x0a",PRN_V_PITCH);    /* 縦ギャップ */
  51.             fprintf(fp,"[LEFT_MARGIN=%d]\x0d\x0a",PRN_LEFT_MARGIN);    /* 左マージン */
  52.             fprintf(fp,"[UP_MARGIN=%d]\x0d\x0a",PRN_UP_MARGIN);    /* 上マージン */
  53.         }
  54. #if 0
  55.         fprintf(fp,"[BAK=%d]\x0d\x0a",CURRENT_BAK);    /* ~.BAK を作るのか? */
  56.         fprintf(fp,"[MODE=%s]\x0d\x0a",(CMDMOD)?"ED":"ME");    /* モード */
  57. #endif
  58.         fprintf(fp,"[ThunderWord Control End]\x0d\x0a");
  59.     }
  60.     if (h) {
  61.         wp = h;
  62.     } else {
  63.         wp = HEAD->ATO;            /* 最初の一行 */
  64.     }
  65.  
  66.     if (!last) {
  67.         last = TAIL;
  68.     }
  69.  
  70.     while(wp != last) {
  71.         p = s;
  72.         line_get_body(s,wp);    /* s がバッファの実体 */
  73.         q = d;            /* d が掃除後のバッファの実体 */
  74.         while(c = *p++) {
  75.             if (c == XCODE_UP) {
  76.                 register UBYTE c0;
  77.  
  78.                 c0 = *p++;    /* 次の1バイト */
  79.  
  80.                 switch(c0) {
  81.                 case XCODE_MARK+0:
  82.                 case XCODE_MARK+1:
  83.                 case XCODE_MARK+2:
  84.                 case XCODE_MARK+3:
  85.                 case XCODE_MARK+4:
  86.                 case XCODE_MARK+5:
  87.                 case XCODE_MARK+6:
  88.                 case XCODE_MARK+7:
  89.                 case XCODE_MARK+8:
  90.                 case XCODE_MARK+9:    /* マーク 0x20 - 0x29 */
  91.                 case XCODE_MARK+10:
  92.                 case XCODE_MARK+11:
  93.                 case XCODE_MARK+12:
  94.                 case XCODE_MARK+13:
  95.                 case XCODE_MARK+14:
  96.                 case XCODE_MARK+15:
  97.     
  98.                 case XCODE_SYSMARK+0:    /* システムマーク */
  99.                 case XCODE_SYSMARK+1:
  100.                 case XCODE_SYSMARK+2:
  101.                 case XCODE_SYSMARK+3:
  102.                 case XCODE_SYSMARK+4:
  103.                 case XCODE_SYSMARK+5:
  104.                 case XCODE_SYSMARK+6:
  105.                 case XCODE_SYSMARK+7:
  106.                 case XCODE_SYSMARK+8:
  107.                 case XCODE_SYSMARK+9:
  108.                 case XCODE_SYSMARK+10:
  109.                 case XCODE_SYSMARK+11:
  110.                 case XCODE_SYSMARK+12:
  111.                 case XCODE_SYSMARK+13:
  112.                 case XCODE_SYSMARK+14:
  113.                 case XCODE_SYSMARK+15:
  114.                 break;    /* マークは捨てる */
  115.  
  116.                 case XCODE_UL:    /* 下線 */
  117.                 *q++ = c;
  118.                 *q++ = c0;
  119.                 break;    /* 下線は書き込む */
  120.     
  121.                 case XCODE_RB10:    /* 予約:1文字真ん中ルビ */
  122.                 case XCODE_RB1:        /* 1文字ルビ */
  123.                 case XCODE_RB1L:    /* 1文字ルビ左(全角用) */
  124.                 case XCODE_RB1R:    /* 1文字ルビ右(全角用) */
  125.                 *q++ = c;
  126.                 *q++ = c0;
  127.                 *q++ = *p++;
  128.                 *q++ = *p++;
  129.                 break;            /* ルビであるから、2バイト文字 */
  130.                 case XCODE_RB2:        /* 2文字ルビ(全角用) */
  131.                 *q++ = c;
  132.                 *q++ = c0;
  133.                 *q++ = *p++;
  134.                 *q++ = *p++;
  135.                 *q++ = *p++;
  136.                 *q++ = *p++;
  137.                 break;            /* ルビであるから、2バイト文字 */
  138.                 }
  139.             } else {
  140.                 *q++ = c;
  141.             }
  142.         }
  143.         if ((q != d) && (q[-1] == CR)) {
  144.             q[-1] = (UBYTE) '\x0d';
  145.             *q++ = (UBYTE) '\x0a';
  146.         }
  147.         *q = EOS;
  148.         writeline++;
  149.         if (fputs((char *)d,fp)) {
  150.             error("ファイル書き込みに失敗しました");
  151.             return(0);
  152.         }
  153.         wp = wp->ATO;
  154.     }
  155.     if (fflush(fp)) {
  156.         error("ファイル書き込みに失敗しました");
  157.         return(0);
  158.     }
  159.     fclose(fp);
  160.  
  161.     if (CURRENT_BAK) {    /* ~.BAK を作るのか? */
  162.         UBYTE backname[MAXLINE];
  163.  
  164.         etc_get_pathname_bak(backname,fname);        /* 名前を得る */
  165.         if (fpb = fopen((char *)backname,"rb")) {    /* 存在するか */
  166.             fclose(fpb);            /* クローズする */
  167.             if (fdelete(backname)) {    /* バックアップファイルを削除する */
  168.                             /* 削除できない! エラーは無視 */
  169.                 if (fdelete(fname)) {    /* オリジナルを削除する */
  170.                 /* 削除出来ない! 暫定名で終了 */
  171.                     UBYTE w[MAXLINE];
  172.  
  173.                     sprintf((char *) w,
  174.                     "[ %s に %d 行をセーブしました]",tname,writeline);
  175.                     under_print(w);
  176.                     return(0);
  177.                 }
  178.             } else {    /* 削除出来た */
  179.                 if (frename(fname,backname)) {    /* オリジナルを~.BAKに改名する */
  180.                 /* 改名出来ない! 暫定名で終了 */
  181.                     UBYTE w[MAXLINE];
  182.  
  183.                     sprintf((char *) w,
  184.                     "[ %s に %d 行をセーブしました]",tname,writeline);
  185.                     under_print(w);
  186.                     return(0);
  187.                 } else {    /* 暫定ファイルをリネームする */
  188.                     if (frename(tname,fname)) {
  189.                         error("ファイルの名前変更に失敗しました");
  190.                         return(0);
  191.                     }
  192.                 }
  193.             }
  194.         } else {
  195.             /* ~.BAKは最初から存在しなかった */
  196.             if (fpb = fopen((char *)fname,"rb")) {    /* オリジナルが存在するか */
  197.                 fclose(fpb);            /* クローズする */
  198.                 if (frename(fname,backname)) {    /* オリジナルを~.BAKに改名する */
  199.                         /* 改名できない! */
  200.                     UBYTE w[MAXLINE];
  201.  
  202.                     sprintf((char *) w,
  203.                     "[ %s に %d 行をセーブしました]",tname,writeline);
  204.                     under_print(w);
  205.                     return(0);
  206.                 }
  207.             }
  208.             if (frename(tname,fname)) {
  209.                 error("ファイルの名前変更に失敗しました");
  210.                 return(0);
  211.             }
  212.         }
  213.  
  214.     } else {    /* BAK 作らないモード */
  215.         if (fpb = fopen((char *)fname,"rb")) {    /* オリジナルが存在するか */
  216.             fclose(fpb);            /* クローズする */
  217.             if (fdelete(fname)) {
  218.                 /* 削除出来ない! */
  219.                 UBYTE w[MAXLINE];
  220.  
  221.                 sprintf((char *) w,"[ %s に %d 行をセーブしました]",tname,writeline);
  222.                 under_print(w);
  223.                 return(0);
  224.             } else {    /* 削除出来た */
  225.                 if (frename(tname,fname)) {
  226.                     error("ファイルの名前変更に失敗しました");
  227.                     return(0);
  228.                 }
  229.             }
  230.         } else {
  231.             if (frename(tname,fname)) {
  232.                 error("ファイルの名前変更に失敗しました");
  233.                 return(0);
  234.             }
  235.         }
  236.     }
  237.  
  238.     {
  239.          UBYTE w[MAXLINE];
  240.         sprintf((char *) w,"[ %d 行]",writeline);
  241.         under_print(w);
  242.     }
  243.     return(1);
  244. }
  245.  
  246. void
  247. buff_read_file_x(int tn)
  248. {
  249.     UBYTE s[MAXLINE];
  250.  
  251.     if (tn == CURRENT_TEXT) {
  252.         buff_read_file();
  253.     } else {
  254.         FILE *fp;
  255.         UBYTE s[MAXLINE];
  256.  
  257.         *s = EOS;    /* 前からの繰り越しはなし */
  258.         fp = FILE_POINTERS[tn];
  259.         if (!fp) {    /* 実物がない */
  260.             buff_read_file_new_x(tn);
  261.         } else {    /* 実物がある */
  262. /*            init_skip_cnf(fp,s);*/
  263.             init_by_cnf_or_default_tn(fp,s,tn);
  264.             buff_read_file_ins(fp,s,&TDATA[tn].TEXT_TAILS);
  265.         }
  266.     }
  267. }
  268.  
  269. /* テキストの初期化だけする */
  270. UNIT *
  271. buff_read_file_new_x(int tn)
  272. {
  273.     UNIT *p;
  274.  
  275.     p = line_get_free_and_store((STR)"");
  276.     if (p == NIL) {            /* フリーラインが無い! */
  277.         under_print0((STR)"メモリ不足:途中で中断します。他の文章をすぐ保存して下さい [Y]? ");
  278.         etc_wait_y();
  279.         return(&AXE);
  280. /*        etc_om_exit();*/
  281.     } else {
  282.         line_insert1_mae(p,&TDATA[tn].TEXT_TAILS);
  283.     }
  284.     return(p);
  285. }
  286.  
  287. /* テキストの初期化だけする */
  288. int
  289. buff_read_file_new()
  290. {
  291.     CL = buff_read_file_new_x(CURRENT_TEXT);
  292.     under_print((STR)"[ 新規ファイル ]");
  293.     disp_btm_line(CWN);
  294.     meta_left_blaket();
  295.     return(0);
  296. }
  297.  
  298. /* ファイルの読み込み */
  299. /* カレントバッファ(空)にカレントファイルを読み込む */
  300. /* error = -1 */
  301. int
  302. buff_read_file()
  303. {
  304.     FILE *fp;
  305.  
  306.     CL = NIL;
  307.     *s = EOS;                /* 前からの繰り越しはなし */
  308.     fp = FILE_POINTERS[CURRENT_TEXT];
  309.     if (!fp) {
  310.         buff_read_file_new();
  311.         init_get_default_tn(CURRENT_TEXT);
  312.         return(0);
  313.     }
  314.     init_by_cnf_or_default_tn(fp,s,CURRENT_TEXT);
  315.     under_print0((STR)"[ファイル読み込み中…]");    /* 時間の掛かる作業の時はメッセージを出す */
  316.  
  317.     buff_read_file_ins(fp,s,TAIL);
  318.     fclose(fp);
  319.     under_blanc();
  320.     disp_btm_line(CWN);
  321.     meta_left_blaket();
  322.     return(0);
  323. }
  324.  
  325. /* 先頭に s を付けてカレントテキストに挿入する */
  326. /* 生成した行数を返す */
  327. /* 挿入後、最後に改行が無く、しかも TAIL の前でなければ改行を付け加える */
  328. int
  329. buff_read_file_ins(FILE *fp,STR s,UNIT *cl)
  330. {
  331.     register int lc=0;
  332.     register UINT jizume,jizume4;
  333.     register UINT jizume3;
  334.     UINT slen;
  335.     UNIT *p,*cl0;
  336.  
  337.     cl0 = cl->MAE;
  338.     jizume = CURRENT_JIZUME;
  339. /*    jizume3 = jizume+3;*/
  340.     jizume4 = jizume+4;
  341.     do {
  342.         if (!*s) {
  343.             fgets((char *)s,jizume4,fp);    /* s がヌルなら適当な長さだけ読み出す */
  344.         }
  345.  
  346.         while(1) {
  347.             if (((slen = strlen(s)) >= 2) &&
  348.             (s[slen-1] == CR) && (s[slen-2] == '\x0d')) {
  349.                 s[slen-2] = CR;
  350.                 s[slen-1] = EOS;
  351.                 break;
  352.             }
  353.             if (string_disp_len(s) > (jizume+6)) {    /* 禁則はみだしがあるので長め */
  354.                 break;
  355.             }
  356.             fgets((char *)l,jizume4,fp);    /* 適当な長さだけ読み出す */
  357.             strcat(s,l);        /* 前からの繰り越しの後に加える */
  358.             if (feof(fp)) break;
  359.         }
  360.  
  361.         if ((cl == CL) && ((CL != NIL) && (!*s))) {    /* feof に達した */
  362.             break;
  363.         }
  364.         cut_line(s,w,s,jizume);
  365.         p = line_get_free_and_store(w);
  366.         if (p == NIL) {            /* フリーラインが無い! */
  367.             etc_beep();
  368.             under_print0((STR)"メモリ不足:途中で中断します。他の文章をすぐ保存して下さい [Y]? ");
  369.             etc_wait_y();
  370.             line_deleten(cl0,cl);
  371.             etc_beep();
  372.             under_print0((STR)"安全のため、読み込んだ文章を破棄しました [Y]? ");
  373.             etc_wait_y();
  374.             return(0);
  375. /*            etc_om_exit();*/
  376.         } else {
  377.             if ((cl == CL) && (CL == NIL)) {
  378.                 CL = p;        /* ポインタの初期化 */
  379.             }
  380.             line_insert1_mae(p,cl);
  381.             lc++;
  382.         }
  383.     } while((!feof(fp)) || (*s));
  384.     if ((etc_last(w) != CR) && (p->ATO != TAIL)) {
  385.         strcat(w,"\n");
  386.         line_store_and_echo(p,w);
  387.     }
  388.     etc_trim_tail();
  389.     return(lc);/* ,,, */
  390. }
  391.  
  392. int
  393. buff_ishan2byte(UBYTE c1)
  394. {
  395.     return((c1 == (UBYTE)'\x80') || ((c1 >= (UBYTE)'\xf0') && (c1 < (UBYTE) XCODE_UP)));
  396. }
  397.  
  398. /* カットバッファに文字列を送り込む */
  399. /* マークコードは取り除く */
  400. /* 文字列の中にマークコードがあったなら対応するビットを立てて返す */
  401. /* 32ビットだよーん */
  402. UINT
  403. buff_add_to_cut_buff(STR s)
  404. {
  405.     UINT mask = 0;
  406.     STR p0;
  407.     register STR p;
  408.  
  409.     p0 = p = s;
  410.     mask = mark_find_mark(s);
  411.     if (mask) {    /* マークを取り除かなければいけない */
  412.         UBYTE w[VERY_LONG_LINE];
  413.         register STR pw;
  414.  
  415.         p = s;
  416.         pw = w;
  417.         while(*p) {
  418.             if ((*pw++ = *p++) == XCODE_UP) {
  419.                 if ((XCODE_MARK <= *p) && (*p <= (XCODE_MARKLAST))) {
  420.                         /* マークだ! */
  421.                     mask |= (1 << (*p - XCODE_MARK));
  422.                     pw--;
  423.                     p++;
  424.                 }
  425.             }
  426.         }
  427.         *pw = EOS;
  428.         p0 = w;
  429.     }
  430.     line_append_cut_buff_list(p0);
  431.     return(mask);
  432. }
  433.  
  434. /* カットバッファから文字列を取り出す */
  435. /* 指定されたユニット番号から、指定されたバイト数を渡す */
  436. /* l == 0 だと、最初の一行を無条件に渡す */
  437. /* 何ユニット目を渡したかを返す。-1なら何も渡せない */
  438. int
  439. buff_get_from_cut_buff(STR s,int l,int begin)
  440. {
  441.     UNIT *wp,*wp0;
  442.     UBYTE w[VERY_LONG_LINE];
  443.     UINT len = 0;
  444.     int i;
  445.  
  446.     *s = EOS;
  447.     wp = CUT_BUFF_HEAD;
  448.     for(i = 0;i < begin;i++) {
  449.         if (wp == NIL) return(-1);    /* 最初のユニットに達する前に終わった */
  450.         wp = wp->ATO;
  451.     }
  452.  
  453.     if (wp == NIL) return(-1);    /* 最初のユニットに達する前に終わった */
  454.     while(wp) {
  455.         line_get_body(w,wp);
  456.         strcat(s,w);            /* 追加する */
  457.         len += wp->LENGTH;
  458.         if ((wp = wp->ATO) == NIL) {
  459.             break;
  460.         }
  461.         if (len < l) {    /* まだ足りない */
  462.             i++;
  463.             continue;        /* 続行 */
  464.         } else {            /* ちょうどもしくは長い */
  465.             break;            /* 拡張コードなどの関係があるのでこうなってる */
  466.         }
  467.     }
  468.     return(i);
  469. }
  470.  
  471. UNIT *
  472. line_append_cut_buff_list(UBYTE *s)
  473. {
  474.     UNIT *p;
  475.     
  476.     if (!(p = line_get_free_and_store(s))) return(NIL);
  477.  
  478.     if (CUT_BUFF_HEAD) {        /* 袋リストがある */
  479.         CUT_BUFF_TAIL->ATO = p;    /* 最後の次が手持ちになる */
  480.         p->MAE = CUT_BUFF_TAIL;    /* 手持ちの前は最後 */
  481.         p->ATO = NIL;        /* 新しい最後は NIL を指す */
  482.         CUT_BUFF_TAIL = p;    /* 新しい最後を指す */
  483.     } else {            /* フリーラインがない */
  484.         CUT_BUFF_HEAD = CUT_BUFF_TAIL = p;
  485.         p->MAE = p->ATO = NIL;
  486.     }
  487.     return(p);
  488. }
  489.  
  490. void
  491. buff_clear_cut_buff()
  492. {
  493.     line_deleten_list(CUT_BUFF_HEAD,CUT_BUFF_TAIL);
  494.     CUT_BUFF_HEAD = CUT_BUFF_TAIL = NIL;
  495.     line_deleten_list(CUT_BUFF_HEAD0,CUT_BUFF_TAIL0);
  496.     CUT_BUFF_HEAD0 = CUT_BUFF_TAIL0 = NIL;
  497. }
  498.